package com.smart.village.big.screen.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.smart.village.big.screen.domain.*;
import com.smart.village.big.screen.mapper.GridInformationMapper;
import com.smart.village.big.screen.service.GovernanceService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class GovernanceServiceImpl implements GovernanceService {

    @Autowired
    private GridInformationMapper gridInformationMapper;

    @Override
    public JSONObject getGridManageStatic(String partyOrganizationSerialNumber) {
        GridInformation giParam = new GridInformation();
        giParam.setResponsibleOrganization(partyOrganizationSerialNumber);
        List<GridInformation> gridInformation =
                gridInformationMapper.getGridInformation(giParam);

        int gridTotalCnt = gridInformation.size();
        int gridManagerCnt = 0;
        int gridOperatorCnt = 0;
        int blueManagerCnt = 0;
        int unitManagerCnt = 0;
        for (GridInformation gi : gridInformation) {
            GridMember gm = new GridMember();
            gm.setGridSerialNumber(gi.getGridSerialNumber());
            gm.setRole("2");
            List<GridMember> role2List = gridInformationMapper.getGridMemberList(gm);
            gridManagerCnt += role2List.size();

            gm.setRole("3");
            List<GridMember> role3List = gridInformationMapper.getGridMemberList(gm);
            gridOperatorCnt += role3List.size();

            gm.setRole("4");
            List<GridMember> role4List = gridInformationMapper.getGridMemberList(gm);
            gridOperatorCnt += role4List.size();

            List<BluePlateInformation> bluePlateInformationByGridSerialNumber =
                    gridInformationMapper.getBluePlateInformationByGridSerialNumber(gi.getGridSerialNumber());
            blueManagerCnt += bluePlateInformationByGridSerialNumber.size();
            for (BluePlateInformation bluePlateInformation : bluePlateInformationByGridSerialNumber) {
                List<BluePlateHouseUnit> bluePlateHouseUnitBluePlateSerialNumber = gridInformationMapper.getBluePlateHouseUnitBluePlateSerialNumber(bluePlateInformation.getBluePlateSerialNumber());
                unitManagerCnt += bluePlateHouseUnitBluePlateSerialNumber.size();
            }
        }
        JSONObject jsonObject = new JSONObject();

        jsonObject.put("gridTotalCnt", gridTotalCnt);
        jsonObject.put("gridManagerCnt", gridManagerCnt);
        jsonObject.put("gridOperatorCnt", gridOperatorCnt);
        jsonObject.put("blueManagerCnt", blueManagerCnt);
        jsonObject.put("unitManagerCnt", unitManagerCnt);
        return jsonObject;
    }

    @Override
    public List<GridMember> getGridMember(String partyOrganizationSerialNumber, String role) {
        GridInformation giParam = new GridInformation();
        giParam.setResponsibleOrganization(partyOrganizationSerialNumber);
        List<GridInformation> gridInformation =
                gridInformationMapper.getGridInformation(giParam);
        List<GridMember> gridMemberList = new ArrayList<GridMember>();
        for (GridInformation gi : gridInformation) {
            GridMember gm = new GridMember();
            gm.setGridSerialNumber(gi.getGridSerialNumber());
            gm.setRole(role);
            gridMemberList.addAll(gridInformationMapper.getGridMemberList(gm));
        }
        return gridMemberList;
    }

    @Override
    public JSONObject getGridInformationCoordsByVillage(String townNumber, String villageNumber) {
        List<GridInformation> gridInformation =
                gridInformationMapper.getGridInformationByVillage(townNumber, villageNumber);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", "FeatureCollection");
        JSONObject crs = new JSONObject();
        crs.put("type", "name");
        JSONObject properties1 = new JSONObject();
        properties1.put("name", "EPSG:4490");
        crs.put("properties", properties1);
        jsonObject.put("crs", crs);
        List<JSONObject> features = Lists.newArrayList();
        gridInformation.forEach(gridInformation1 -> {
            JSONObject feature = new JSONObject();
            feature.put("type", "Feature");
            feature.put("id", gridInformation1.getGridSerialNumber());
            JSONObject geometry = new JSONObject();
            geometry.put("type", "Polygon");
            geometry.put("coordinates", gridInformation1.getCoords());
            feature.put("geometry", geometry);
            JSONObject properties = new JSONObject();
            properties.put("FID", gridInformation1.getGridSerialNumber());
            properties.put("id", gridInformation1.getGridSerialNumber());
            String gridName = gridInformation1.getGridName();
            properties.put("name", gridName);
            feature.put("properties", properties);
            features.add(feature);
        });
        jsonObject.put("features", features);
        return jsonObject;
    }

    @Override
    public List<GridInformationStaticVo> getGridInformationByVillage(String townNumber,
                                                                     String villageNumber
    ) {
        List<GridInformationStaticVo> gridInformationList = Lists.newArrayList();

        List<GridInformation> gridInformationByVillage =
                gridInformationMapper.getGridInformationByVillage(townNumber, villageNumber);

        gridInformationByVillage.forEach(gi -> {
            GridInformationStaticVo gridInformationStaticVo = new GridInformationStaticVo();
            BeanUtils.copyProperties(gi, gridInformationStaticVo);
            GridMember gm = new GridMember();
            gm.setGridSerialNumber(gi.getGridSerialNumber());
            gm.setRole("2");

            List<GridMember> memberList = gridInformationMapper.getGridMemberList(gm);

            memberList.forEach(member -> {
                if (member.getRole().equals("2")) {
                    gridInformationStaticVo.setGridMemberManager(member.getPersonalName());
                }
            });
            gridInformationList.add(gridInformationStaticVo);
        });

        return gridInformationList;
    }

    @Override
    public GridInformationVo getGridInformationByGridSerialNumber(String gridSerialNumber) {
        GridInformationVo gridInformationVo = new GridInformationVo();
        GridInformation gi = gridInformationMapper.getGridInformationByGridSerialNumber(gridSerialNumber);
        BeanUtils.copyProperties(gi, gridInformationVo);
        JSONObject residentVillageSecretary = gridInformationMapper.getResidentVillageSecretary(gi.getVillageNumber());
        if(!ObjectUtils.isEmpty(residentVillageSecretary)) {
            gridInformationVo.setResidentVillageSecretary(residentVillageSecretary.get("Personal_Name").toString());
            gridInformationVo.setResidentIdCardNumber(residentVillageSecretary.get("ID_Card_Number").toString());
        }
        if (!ObjectUtils.isEmpty(gi)) {
            GridMember gm = new GridMember();
            gm.setGridSerialNumber(gi.getGridSerialNumber());

            List<GridMember> memberList = gridInformationMapper.getGridMemberList(gm);

            memberList.forEach(member -> {

                if (member.getRole().equals("2")) {
                    member.setRole("专职网格员");
                    gridInformationVo.setGridMemberManager(member.getPersonalName());
                }
                if (member.getRole().equals("3")) {
                    member.setRole("兼职网格员");
                }
                if (member.getRole().equals("4")) {
                    member.setRole("专业网格员");
                }
            });
            gridInformationVo.setGridMemberList(memberList);
            List<BluePlateInformation> bindBluePlateInfomationList = gridInformationMapper.getBindBluePlateInformationByGridSerialNumber(gridSerialNumber);
            bindBluePlateInfomationList.forEach(bp -> {
                List<PersonalInformation> importentPersonListByBluePlateSerialNumber = gridInformationMapper.getImportentPersonListByBluePlateSerialNumber(bp.getBluePlateSerialNumber());
                importentPersonListByBluePlateSerialNumber.forEach(person -> {
                    List<PersonalMappingTags> personTagsByIdCardNumber = gridInformationMapper.getPersonTagsByIdCardNumber(person.getIdCardNumber());
                    person.setTags(personTagsByIdCardNumber);
                });
                bp.setImportentPersonList(importentPersonListByBluePlateSerialNumber);
            });

            gridInformationVo.setBindBluePlateInfomationList(bindBluePlateInfomationList);
        }
       return gridInformationVo;
    }

    @Override
    public JSONObject getVillageBaseInformation(String townNumber, String villageNumber) {
        JSONObject districtIntroduction = gridInformationMapper.getDistrictIntroduction(townNumber, villageNumber);

        JSONObject villageBaseInformation = gridInformationMapper.getVillageBaseInformation(townNumber, villageNumber);
        districtIntroduction.forEach((key, value) -> {
            villageBaseInformation.put(key, value);
        });

        List<GridInformation> gridInformation =
                gridInformationMapper.getGridInformationByVillage(townNumber, villageNumber);
        if(CollectionUtils.isEmpty(gridInformation)) {
            villageBaseInformation.put("gridCnt",0);
        }else {
            villageBaseInformation.put("gridCnt", gridInformation.size());
        }
        return villageBaseInformation;
    }

    @Override
    public JSONObject getVillagerCoGovernance(String townNumber, String villageNumber) {
        JSONObject result = new JSONObject();

        List<JSONObject> villagerCoGovernance = gridInformationMapper.getVillagerCoGovernance(townNumber, villageNumber);
        villagerCoGovernance.forEach(jsonObject -> {
            if (jsonObject.getString("type").equals("今日上报")) {
                result.put("upCnt",jsonObject.getInteger("cnt"));
            }
            if (jsonObject.getString("type").equals("今日处理")) {
                result.put("doneCnt",jsonObject.getInteger("cnt"));
            }
            if (jsonObject.getString("type").equals("待处理")) {
                result.put("willCnt",jsonObject.getInteger("cnt"));
            }

        });
        if(result.containsKey("upCnt")&&result.getInteger("upCnt")==0){
            result.put("finishPercent",0);
        }
        if(result.containsKey("doneCnt")&&result.getInteger("doneCnt")==0){
            result.put("finishPercent",0);
        }
        if(result.containsKey("upCnt")&&result.getInteger("upCnt")!=0){
            Integer doneCnt = result.getInteger("doneCnt");
            Integer upCnt = result.getInteger("upCnt");
            double v = doneCnt.doubleValue() / upCnt.doubleValue();
            DecimalFormat df = new DecimalFormat("#.00");
            String str = df.format(v*100);
            result.put("finishPercent",new BigDecimal(str));
        }
        return result;
    }

    @Override
    public List<JSONObject> getVillagerCoGovernance2(String townNumber, String villageNumber, String searchType) {
        if( StringUtils.isEmpty(searchType)) {
            return Lists.newArrayList();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        switch (searchType) {
            case "threeYear" -> {
                calendar.add(Calendar.YEAR, -3);
                Date timeThreeYearAgo = calendar.getTime();
                String yearThreeYearAgo = DateFormatUtils.format(timeThreeYearAgo, "yyyy");
                String nowYear = DateFormatUtils.format(new Date(), "yyyy");
                return gridInformationMapper.getVillagerCoGovernance2(townNumber, villageNumber, searchType, yearThreeYearAgo, nowYear);
            }
            case "currentWeek" -> {
                LocalDate today = LocalDate.now();
                LocalDate firstDayOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
                DateTimeFormatter simpleDateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String currentWeekFirst =   firstDayOfWeek.format(simpleDateFormat);
                String currentNow = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
                return gridInformationMapper.getVillagerCoGovernance2(townNumber, villageNumber, searchType, currentWeekFirst, currentNow);
            }
            case "currentMonth" -> {
                String currentMonth = DateFormatUtils.format(new Date(), "yyyy-MM");
                return gridInformationMapper.getVillagerCoGovernance2(townNumber, villageNumber, searchType, currentMonth, currentMonth);
            }
        }
        return Lists.newArrayList();
    }

    @Override
    public List<JSONObject> getVillagerCoGovernance3(String townNumber, String villageNumber, String searchType) {
        if( StringUtils.isEmpty(searchType)) {
            return Lists.newArrayList();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        switch (searchType) {
            case "currentWeek" -> {
                LocalDate today = LocalDate.now();
                LocalDate firstDayOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
                DateTimeFormatter simpleDateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String currentWeekFirst =   firstDayOfWeek.format(simpleDateFormat);
                String currentNow = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
                List<JSONObject> villagerCoGovernance3 = gridInformationMapper.getVillagerCoGovernance3(townNumber, villageNumber, searchType, currentWeekFirst, currentNow);
                villagerCoGovernance3.forEach(jsonObject -> {
                    String gridSerialNumber = jsonObject.getString("Grid_SerialNumber");
                    GridMember gm = new GridMember();
                    gm.setGridSerialNumber(gridSerialNumber);
                    gm.setRole("2");

                    List<GridMember> memberList = gridInformationMapper.getGridMemberList(gm);

                    memberList.forEach(member -> {
                        if (member.getRole().equals("2")) {
                            jsonObject.put("gridMemberManager",member.getPersonalName());
                        }
                    });
                });
                return villagerCoGovernance3;
            }
            case "currentMonth" -> {
                String currentMonth = DateFormatUtils.format(new Date(), "yyyy-MM");
                List<JSONObject> villagerCoGovernance3 = gridInformationMapper.getVillagerCoGovernance3(townNumber, villageNumber, searchType, currentMonth, currentMonth);
                villagerCoGovernance3.forEach(jsonObject -> {
                    String gridSerialNumber = jsonObject.getString("Grid_SerialNumber");
                    GridMember gm = new GridMember();
                    gm.setGridSerialNumber(gridSerialNumber);
                    gm.setRole("2");

                    List<GridMember> memberList = gridInformationMapper.getGridMemberList(gm);

                    memberList.forEach(member -> {
                        if (member.getRole().equals("2")) {
                            jsonObject.put("gridMemberManager",member.getPersonalName());
                        }
                    });
                });
                return villagerCoGovernance3;
            }
        }
        return Lists.newArrayList();
    }

    @Override
    public List<JSONObject> getGridEventList(String gridSerialNumber, String searchType) {
        if( StringUtils.isEmpty(searchType)) {
            return Lists.newArrayList();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        switch (searchType) {
            case "currentWeek" -> {
                LocalDate today = LocalDate.now();
                LocalDate firstDayOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
                DateTimeFormatter simpleDateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String currentWeekFirst =   firstDayOfWeek.format(simpleDateFormat);
                String currentNow = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
                List<JSONObject> villagerCoGovernance3 = gridInformationMapper.getGridEventList(gridSerialNumber, searchType, currentWeekFirst, currentNow);
                return villagerCoGovernance3;
            }
            case "currentMonth" -> {
                String currentMonth = DateFormatUtils.format(new Date(), "yyyy-MM");
                List<JSONObject> villagerCoGovernance3 = gridInformationMapper.getGridEventList(gridSerialNumber, searchType, currentMonth, currentMonth);
                return villagerCoGovernance3;
            }
        }
        return Lists.newArrayList();
    }

    @Override
    public List<JSONObject> getDigitalDoorplateStatics(String townNumber, String villageNumber,String BPHTSerialNumber) {
        return gridInformationMapper.getDigitalDoorplateStatics(townNumber,villageNumber,BPHTSerialNumber);
    }

    @Override
    public List<JSONObject> getDigitalDoorplateStaticsTagList() {
        return gridInformationMapper.getDigitalDoorplateStaticsTagList();
    }

    @Override
    public JSONObject getComprehensiveGridManageStatic(String townNumber, String villageNumber) {

        List<GridInformation> gridInformation =
                gridInformationMapper.getComprehensiveGridManageStatic(townNumber,villageNumber);

        int gridTotalCnt = gridInformation.size();
        int gridManagerCnt = 0;
        int gridOperatorCnt = 0;
        int blueManagerCnt = 0;
        int unitManagerCnt = 0;
        for (GridInformation gi : gridInformation) {
            GridMember gm = new GridMember();
            gm.setGridSerialNumber(gi.getGridSerialNumber());
            gm.setRole("2");
            List<GridMember> role2List = gridInformationMapper.getGridMemberList(gm);
            gridManagerCnt += role2List.size();

            gm.setRole("3");
            List<GridMember> role3List = gridInformationMapper.getGridMemberList(gm);
            gridOperatorCnt += role3List.size();

            gm.setRole("4");
            List<GridMember> role4List = gridInformationMapper.getGridMemberList(gm);
            gridOperatorCnt += role4List.size();

            List<BluePlateInformation> bluePlateInformationByGridSerialNumber =
                    gridInformationMapper.getBluePlateInformationByGridSerialNumber(gi.getGridSerialNumber());
            blueManagerCnt += bluePlateInformationByGridSerialNumber.size();
            for (BluePlateInformation bluePlateInformation : bluePlateInformationByGridSerialNumber) {
                List<BluePlateHouseUnit> bluePlateHouseUnitBluePlateSerialNumber = gridInformationMapper.getBluePlateHouseUnitBluePlateSerialNumber(bluePlateInformation.getBluePlateSerialNumber());
                unitManagerCnt += bluePlateHouseUnitBluePlateSerialNumber.size();
            }
        }
        JSONObject jsonObject = new JSONObject();

        jsonObject.put("gridTotalCnt", gridTotalCnt);
        jsonObject.put("gridManagerCnt", gridManagerCnt);
        jsonObject.put("gridOperatorCnt", gridOperatorCnt);
        jsonObject.put("blueManagerCnt", blueManagerCnt);
        jsonObject.put("unitManagerCnt", unitManagerCnt);
        return jsonObject;
    }

    @Override
    public JSONObject getComplaintsList(String townNumber, String villageNumber,int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1);
        Date timeOneMonthAgo = calendar.getTime();
        String dayOneMonthAgo = DateFormatUtils.format(timeOneMonthAgo, "yyyy-MM-dd");
        String now= DateFormatUtils.format(new Date(), "yyyy-MM-dd");
        List<JSONObject> complaintsList = gridInformationMapper.getComplaintsList(townNumber, villageNumber, dayOneMonthAgo, now);
        PageInfo<JSONObject> pageInfo = new PageInfo<>(complaintsList);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("list", pageInfo.getList());
        jsonObject.put("total", pageInfo.getTotal());
        return jsonObject;
    }

    @Override
    public JSONObject getComplaintsDetail(String complaintId) {
        JSONObject complaintsDetail = gridInformationMapper.getComplaintsDetail(complaintId);
        if(ObjectUtils.isEmpty(complaintsDetail)){
            return new JSONObject();
        }
        return complaintsDetail;
    }

    @Override
    public List<JSONObject> getComplaintsDetailFullImage(String complaintId) {
        return gridInformationMapper.getComplaintsDetailFullImage(complaintId);
    }

    @Override
    public List<JSONObject> getComplaintsLastestDynamic(String complaintId) {
        return gridInformationMapper.getComplaintsLastestDynamic(complaintId);
    }

    @Override
    public List<JSONObject> getComplaintsLastProgress(String townNumber, String villageNumber) {
        List<JSONObject> complaintsLastProgress = gridInformationMapper.getComplaintsLastProgress(townNumber, villageNumber);
        for (int i = 0; i < complaintsLastProgress.size(); i++) {
            complaintsLastProgress.get(i).put("rank",i+1);
        }
        return complaintsLastProgress;
    }

    @Override
    public List<JSONObject> getPatrolCheckIn(String townNumber, String villageNumber) {
        return gridInformationMapper.getPatrolCheckIn(townNumber, villageNumber);
    }

    @Override
    public JSONObject getInspectionVisitSituation(String townNumber, String villageNumber) {
        JSONObject jsonObject = new JSONObject();
        String Focus;
        String Grid_Member;
        String Event_Deal;
        String Visit_Rate;

        Focus = gridInformationMapper.getInspectionVisitSituationFocus(townNumber,villageNumber);
        Grid_Member = gridInformationMapper.getInspectionVisitSituationGridMember(townNumber,villageNumber);
        Event_Deal = gridInformationMapper.getInspectionVisitSituationEventDeal(townNumber,villageNumber);
        Visit_Rate = gridInformationMapper.getInspectionVisitSituationVisitRate(townNumber,villageNumber);

        jsonObject.put("Focus", Focus);
        jsonObject.put("Grid_Member", Grid_Member);
        jsonObject.put("Event_Deal", Event_Deal);
        jsonObject.put("Visit_Rate", StringUtils.isEmpty(Visit_Rate)?"0":Visit_Rate);

        return jsonObject;
    }


}
